package org.xiaoxi.service;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xiaoxi.cache.impl.UrlCacheImpl;
import org.xiaoxi.dao.TinyurlDao;
import org.xiaoxi.entity.Tinyurl;
import org.xiaoxi.exception.TinyurlException;
import org.xiaoxi.rateLimiter.dao.RedisClient;
import org.xiaoxi.utils.DecimalTransfer;

import com.wcansoft.baseWeb.mybatis_plugin.dao.MybatisBaseDAO;
import com.wcansoft.baseWeb.mybatis_plugin.dao.Query;
import com.wcansoft.baseWeb.mybatis_plugin.service.BaseService;

/**
 * Created by YanYang on 2016/6/18.
 */
@Service
public class TinyurlService extends BaseService<Tinyurl>{
	private static final Logger LOGGER = LoggerFactory
			.getLogger(TinyurlService.class);

	@Autowired
	private TinyurlDao tinyurlDao;

	@Autowired
	private UrlCacheImpl urlCache;

	public long insertTinyurl(Tinyurl tinyurl) {
		return tinyurlDao.insertUrl(tinyurl);
	}

	public Tinyurl getIdByUrl(String url) {
		return tinyurlDao.getIdByUrl(url);
	}

	public Tinyurl getUrlById(long id) {
		return tinyurlDao.getUrlById(id);
	}

	public int updateTinyUrl(long id, String shortUrl) {
		return tinyurlDao.updateTinyUrl(id, shortUrl);
	}

	public Tinyurl getUrlByShortUrl(String shortUrl) {
		return tinyurlDao.getUrlByShortUrl(shortUrl);
	}
	
	
	public List<Tinyurl> transferToShort_urls(String long_urls, Integer seconds){

		/**
		 * step1、查询数据库
		 * step2、有直接返回，没有进行生成然后插入
		 * 
		 * 
		 * 
		 */
		String[] arr=long_urls.split(",");
		String qSql="";
		for(String long_url:arr){
			qSql+="\""+long_url+"\",";
		}
		qSql=qSql.substring(0, qSql.length()-1);
		
		String sql=" select id, url,short_url as shortUrl from tinyurl where  url in ("+qSql+")  ";
		List<Tinyurl> list=this.listQuery(new Query(sql));
		if(list !=null && list.size()>0){//FIXME 可能会出现部分没有转化过的情况
			return list;
		}else{//进行插入数据库的操作
			list=new ArrayList<Tinyurl>();
			
			for(String long_url:arr){
				String short_url="";
				Tinyurl tinyurl= new Tinyurl(long_url);
				long id = insertTinyurl(tinyurl); // 返回的id是插入影响行数，插入后生成的id会放入tinurl对象中
				if (id > 0) {
					long short_id = tinyurl.getId();
					// 生成对应的短链接
					String[] shortUrls = null;
					shortUrls = DecimalTransfer.longUrl2ShortUrl(long_url, ""+ short_id);
					if (shortUrls == null || shortUrls.length < 1) {
						return null;
					}
					b:for (String shortStr : shortUrls) {// 如果都失败的情况，FIXME 需要考虑下
						int i = 0;
						try {
							i = updateTinyUrl(short_id, shortStr);
						} catch (Exception e) {
							LOGGER.info("shorturl update fail :" + shortStr
									+ "," + short_id + e.getMessage());
							continue b;
						}
						if (i != 1) {
							LOGGER.info("shorturl update fail :" + shortStr
									+ "," + short_id);
							continue b;
						} else {//插入成功 进行处理
							short_url = shortStr;
							tinyurl.setShortUrl(short_url);
							list.add(tinyurl);
							break b;
						}
					}
					if (short_url == null) { //小概率时间
						throw new TinyurlException(long_url+ " 插入失败 or shorturl repeat"); //FIXME 回滚
					}
					
					try {
						urlCache.set(short_url, long_url, seconds);
					} catch (Exception e) {//设置缓存  设置失败  小概率时间
						
						e.printStackTrace();
						LOGGER.info("设置缓存失败："+short_url);
					}
																
				}
			}
			
			return list;
			
		}
		
		
		
		
		
		
		
		
	}
	
	
	
	/**
	 * 
	 * @描述 ：长连接转化成短连接
	 * @创建人：zhongy
	 * @创建时间：2017年2月4日 下午3:27:21
	 * @修改人：
	 * @修改时间：
	 * @修改描述：
	 * @param long_url
	 *            待转化长链接
	 * @return 短链接
	 * @throws TinyurlException
	 */
	@Transactional
	public String transferToShort_url(String long_url, Integer seconds)
			throws TinyurlException {
		try {
			String short_url = null;
			// 先查缓存redis
			short_url = urlCache.getShort_url(long_url);
			// 缓存命中
			if (short_url != null && !short_url.equals("")) {
				return short_url;
			}
			// 缓存未命中，查数据库 DB
			Tinyurl tinyurl = getIdByUrl(long_url);
			if (tinyurl == null) {
				tinyurl = new Tinyurl(long_url);
				long id = insertTinyurl(tinyurl); // 返回的id是插入影响行数，插入后生成的id会放入tinurl对象中
				if (id > 0) {
					long short_id = tinyurl.getId();
					// 生成对应的短链接
					String[] shortUrls = null;
					shortUrls = DecimalTransfer.longUrl2ShortUrl(long_url, ""
							+ short_id);
					if (shortUrls == null || shortUrls.length < 1) {
						return null;
					}
					for (String shortStr : shortUrls) {// 如果都失败的情况，FIXME 需要考虑下
						int i = 0;
						try {
							i = updateTinyUrl(short_id, shortStr);
						} catch (Exception e) {
							LOGGER.info("shorturl update fail :" + shortStr
									+ "," + short_id + e.getMessage());
							continue;

						}
						if (i != 1) {
							LOGGER.info("shorturl update fail :" + shortStr
									+ "," + short_id);
							continue;
						} else {
							short_url = shortStr;
							break;
						}
					}
					if (short_url == null) {
						throw new TinyurlException(long_url
								+ " 插入失败 or shorturl repeat");
					}
					// short_url = DecimalTransfer.idToShortUrl(short_id); //
					// 这个方法需要修改
					// updateTinyUrl(short_id,short_url);
					// 加缓存
					urlCache.set(short_url, long_url, seconds);// XXX
																// 这边需要增加存活时间参数
					return short_url;
				} else {
					throw new TinyurlException(long_url + " 插入失败");
				}
			}else{
				short_url=tinyurl.getShortUrl();
			}
			
			// short_url = DecimalTransfer.idToShortUrl(tinyurl.getId());
			urlCache.set(short_url, long_url, seconds);// XXX 这边需要增加存活时间参数
			return short_url;
		} catch (Exception e1) {
			LOGGER.error(e1.getMessage());
			throw new TinyurlException("transferToLong_url" + e1.getMessage());
		}
	}

	public String transferToLong_url(String short_url, Integer seconds)
			throws TinyurlException {
		try {
			if (short_url != null && !short_url.equals("")) {
//				long id = DecimalTransfer.shortUrlToID(short_url);
				// 查询缓存
				String long_url = urlCache.getLong_url(short_url);
				// 缓存命中
				if (long_url != null && !long_url.equals("")) {
					return long_url;
				}
				// 缓存未命中
				Tinyurl tinyurl = getUrlByShortUrl(short_url);//getUrlById(id) XXX
				if (tinyurl != null) {
					urlCache.set(short_url, tinyurl.getUrl(), seconds);
					return tinyurl.getUrl();
				} else {
					throw new TinyurlException("get url by short_url failed");
				}
			} else {
				throw new TinyurlException("short_url is illegal");
			}
		} catch (TinyurlException e) {
			throw e;
		} catch (Exception e1) {
			LOGGER.error(e1.getMessage(), e1);
			throw new TinyurlException("transferToLong_url" + e1.getMessage());
		}
	}

	public static void main(String[] args) {
		String long_url = "http://admin.jifefu.net";
		System.out.println(long_url.substring(RedisClient.REDIS_PRE.length()));
	}

	@Override
	public Class<?> getClazz() {
	
		return Tinyurl.class;
	}


	@Override
	public MybatisBaseDAO<Tinyurl> getImpDao() {
		return tinyurlDao;
	}
}
